package org.newcih.web;

import org.apache.commons.io.FileUtils;
import org.newcih.pojo.Box;
import org.newcih.pojo.ResponseMessage;
import org.newcih.service.MainService;
import org.newcih.train.TessTrainer;
import org.newcih.util.BoxUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.*;

import static org.newcih.util.ImageUtils.mergeMultiTiff;

@Controller
@RequestMapping("/")
public class MainController {

    public static final String     TESS_DIR           = "/usr/bin";
    public static final String     TESS_DATA_DIR      = "/usr/share/tesseract/tessdata/";
    public static final String     INPUTDATA_DIR_ROOT = "/home/newcih/Tesseract/D/";
    public static final String     DEFAULT_FONT_NAME  = "eng";
    public static       String     NEW_FONT_NAME      = UUID.randomUUID().toString();
    public static       List<File> fileList           = new ArrayList<>();

    @RequestMapping(value = "output")
    @ResponseBody
    public List<String> out() throws Exception {
        TessTrainer tessTrainer = new TessTrainer(TESS_DIR, INPUTDATA_DIR_ROOT, DEFAULT_FONT_NAME);
        return tessTrainer.listFonts();
    }

    /**
     * 识别图片接口
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "tesseract")
    @ResponseBody
    public ResponseMessage tesseract(MultipartFile file) {
        String fileName = file.getOriginalFilename();
        String fontName = "eng";
        if (fileName.contains("@")) {
            fontName = fileName.substring(0, fileName.indexOf("@"));
            if (fontName == null || fontName.trim().equals("")) {
                fontName = "eng";
            }
        }

        // 存入本地
        String localFileName = INPUTDATA_DIR_ROOT + fileName;
        try {
            file.transferTo(new File(localFileName));
        } catch (IOException e) {
            e.printStackTrace();
        }

        Map<String, String> valueMap = new HashMap<>();
        // 调用接口
        TessTrainer tessTrainer = new TessTrainer(TESS_DIR, INPUTDATA_DIR_ROOT, fontName);
        try {
            String result = tessTrainer.tesseract(localFileName);
            // 写入返回数据
            valueMap.put("result", result);
            valueMap.put("fileName", fileName);
            return ResponseMessage.ok(ResponseMessage.OK, valueMap);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseMessage.error("识别出错");
        }
    }

    /**
     * 训练图片上传接口
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "train")
    @ResponseBody
    public ResponseMessage train(MultipartFile file) {

        // 创建生产目录
        String INPUTDATA_DIR = MainService.generatorFolder(NEW_FONT_NAME);

        // 序列化图片到目录
        File temp = new File(INPUTDATA_DIR, file.getOriginalFilename());
        fileList.add(temp);
        try {
            file.transferTo(temp);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return ResponseMessage.ok();
    }


    /**
     * 开始训练2
     *
     * @return
     */
    @RequestMapping(value = "train2/start")
    @ResponseBody
    public ResponseMessage startTrain2(@RequestParam("fileName") String fileName,
                                       @RequestParam("result") String result) {

        // 创建生产目录
        String INPUTDATA_DIR = MainService.generatorFolder(NEW_FONT_NAME);

        TessTrainer tessTrainer = new TessTrainer(TESS_DIR, INPUTDATA_DIR, NEW_FONT_NAME);

        try {
            // 生成box文件
            tessTrainer.makeBox(INPUTDATA_DIR_ROOT + fileName);
            // 更新box文件
            File         boxFile   = new File(INPUTDATA_DIR, NEW_FONT_NAME + ".box");
            List<String> valueList = Arrays.asList(result.split(""));

            if (boxFile.exists()) {
                System.out.println("box文件存在");
            } else {
                System.out.println("box文件不存在");
            }

            System.out.println("box文件创建成功");
            BoxUtils.updateBoxFileWithValue(boxFile, valueList);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 图片文件更名(将名字更名为与box文件相同)
        File   imageFile     = new File(INPUTDATA_DIR_ROOT + fileName);
        String extraName     = fileName.substring(fileName.indexOf("."), fileName.length());
        File   imageDestFile = new File(INPUTDATA_DIR, NEW_FONT_NAME + extraName);
        imageFile.renameTo(imageDestFile);

       /*
        File destMultiTiffFile = new File(INPUTDATA_DIR, NEW_FONT_NAME + ".tif");
        try {
            Box box = mergeMultiTiff(fileList, destMultiTiffFile);
            BoxUtils.boxToFile(box, INPUTDATA_DIR + File.separator + NEW_FONT_NAME + ".box");
            System.out.println("插入了" + fileList.size() + "张图片");
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        // 训练并生成训练数据
        try {
            tessTrainer.generateTraineddata();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 将字体数据移动到TESS_DATA目录
        File srcTrainedData  = new File(INPUTDATA_DIR + "/tessdata/" + NEW_FONT_NAME + ".traineddata");
        File destTrainedData = new File(TESS_DATA_DIR + NEW_FONT_NAME + ".traineddata");
        try {
            FileUtils.moveFile(srcTrainedData, destTrainedData);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 清空上传图片列表
        fileList.clear();
        // 生成新的字体名
        String returnResult = NEW_FONT_NAME;
        NEW_FONT_NAME = UUID.randomUUID().toString();

        return ResponseMessage.ok(returnResult);
    }


    /**
     * 开始训练
     *
     * @return
     */
    @RequestMapping(value = "train/start")
    @ResponseBody
    public ResponseMessage startTrain() {

        // 创建生产目录
        String INPUTDATA_DIR = MainService.generatorFolder(NEW_FONT_NAME);

        // 生成box文件
        File destMultiTiffFile = new File(INPUTDATA_DIR, NEW_FONT_NAME + ".tif");
        try {
            Box box = mergeMultiTiff(fileList, destMultiTiffFile);
            BoxUtils.boxToFile(box, INPUTDATA_DIR + File.separator + NEW_FONT_NAME + ".box");
            System.out.println("插入了" + fileList.size() + "张图片");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 训练并生成训练数据
        TessTrainer tessTrainer = new TessTrainer(TESS_DIR, INPUTDATA_DIR, NEW_FONT_NAME);
        try {
            tessTrainer.generateTraineddata();
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 将字体数据移动到TESS_DATA目录
        File srcTrainedData  = new File(INPUTDATA_DIR + "/tessdata/" + NEW_FONT_NAME + ".traineddata");
        File destTrainedData = new File(TESS_DATA_DIR + NEW_FONT_NAME + ".traineddata");
        try {
            FileUtils.moveFile(srcTrainedData, destTrainedData);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 清空上传图片列表
        fileList.clear();
        // 生成新的字体名
        String returnResult = NEW_FONT_NAME;
        NEW_FONT_NAME = UUID.randomUUID().toString();

        return ResponseMessage.ok(returnResult);
    }

    public static void main(String[] args) throws Exception {

    }

}
